package com.llvision.workflow.module.biz;

import com.alibaba.fastjson.JSONObject;
import com.llvision.bean.RequestDTO;
import com.llvision.workflow.base.BaseBiz;
import com.llvision.workflow.common.bean.step.JcStepInfoDTO;
import com.llvision.workflow.common.bean.step.JcStepListDTO;
import com.llvision.workflow.common.bean.step.JcStepOperationDTO;
import com.llvision.workflow.common.constant.C;
import com.llvision.workflow.common.utils.IdUtil;
import com.llvision.workflow.module.dao.JcProceduralStepMapper;
import com.llvision.workflow.module.dao.JcStepAttachmentMapper;
import com.llvision.workflow.module.dao.JcStepItemMapper;
import com.llvision.workflow.module.dao.JcStepToastMapper;
import com.llvision.workflow.module.entity.JcProceduralStep;
import com.llvision.workflow.module.entity.JcStepAttachment;
import com.llvision.workflow.module.entity.JcStepItem;
import com.llvision.workflow.module.entity.JcStepToast;
import com.llvision.workflow.util.BeanConvertUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 步骤逻辑处理层
 * @author xushuanglu
 * @since 2021-06-16
 */
@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class JcProceduralStepBiz extends BaseBiz<JcProceduralStepMapper, JcProceduralStep> {

    @Resource
    private JcProceduralStepMapper jcProceduralStepMapper;

    @Resource
    private JcStepToastMapper jcStepToastMapper;

    @Resource
    private JcStepAttachmentMapper jcStepAttachmentMapper;

    @Resource
    private JcCardBiz jcCardBiz;

    @Resource
    private JcStepItemMapper jcStepItemMapper;


    //##############################################南航二期三阶段新接口开始##################################################

    /**
     * 新增步骤（南航二期三阶段）
     * @param requestDTO 请求参数体
     * @return string
     */
    @Transactional(rollbackFor = Exception.class)
    public String addStepItem(RequestDTO<JcStepOperationDTO> requestDTO) {

        JcStepOperationDTO jcStepInfoDTO = requestDTO.getData();
        log.info("addStepItem requestDTO:{}", ((JSONObject) JSONObject.toJSON(requestDTO)).toJSONString());
        String stepId = IdUtil.getId();
        int maxStepNumber = 1;
        if(StringUtils.isNotBlank(jcStepInfoDTO.getFid())){
            maxStepNumber = jcProceduralStepMapper.getMaxStepNumber(jcStepInfoDTO.getFid());
        }else{
            maxStepNumber = jcProceduralStepMapper.getMaxStepNumber(String.valueOf(C.N_0));
        }

        //处理
        JcProceduralStep jcProceduralStep = JcProceduralStep.build();
        BeanUtils.copyProperties(requestDTO, jcProceduralStep);
        jcProceduralStep.setCompleteConfirm(jcStepInfoDTO.getCompleteConfirm())
                .setStandardTime(jcStepInfoDTO.getStandardTime())
                .setDescription(jcStepInfoDTO.getDescription())
                .setCardId(jcStepInfoDTO.getCardId())
                .setStepNotesCh(jcStepInfoDTO.getStepNotesCh())
                .setStepNotesEn(jcStepInfoDTO.getStepNotesEn())
                .setTitleCh(jcStepInfoDTO.getTitleCh())
                .setTitleEn(jcStepInfoDTO.getTitleEn())
                .setFid(StringUtils.isNotEmpty(jcStepInfoDTO.getFid()) ? jcStepInfoDTO.getFid() : "0")
                .setDelFlag(0).setStepId(stepId).setStepSort(maxStepNumber);
        jcProceduralStepMapper.insertUseGeneratedKeys(jcProceduralStep);
        //添加选项信息
        List<JcStepItem> jcStepItemList = jcStepInfoDTO.getJcStepItemList();
        if(!CollectionUtils.isEmpty(jcStepItemList)){
            jcStepItemList.stream().forEach(stepItem ->  jcStepItemMapper.insert(stepItem.setStepId(String.valueOf(jcProceduralStep.getStepId()))
            .setItemId(IdUtil.getId()).setCardId(jcProceduralStep.getCardId()).setIsOnlyShow(0).setOilStatus(0)
                    /*.setItemTitleCh(stepItem.getItemType() == 4 ? "" : stepItem.getItemTitleCh())
                    .setContent(stepItem.getItemType() == 4 ? stepItem.getItemTitleCh() : stepItem.getContent())*/));
        }

        //添加附件信息
        List<JcStepAttachment> attList = jcStepInfoDTO.getAttList();
        if(!CollectionUtils.isEmpty(attList)){
            attList.stream().forEach(att ->  jcStepAttachmentMapper.insert(att.setCardId(jcProceduralStep.getCardId())));
        }
        //更新版本号
        jcCardBiz.updateVersionByCardId(Integer.valueOf(requestDTO.getData().getCardId()));

        return String.valueOf(jcProceduralStep.getStepId());
    }



    /**
     * 修改步骤接口
     * @param requestDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer updateStepItem(RequestDTO<JcStepOperationDTO> requestDTO) {

        JcStepOperationDTO data = requestDTO.getData();
        //删除之前功能项
        JcStepItem jcStepItem = JcStepItem.build().setStepId(StringUtils.isNotBlank(data.getStepId()) ? data.getStepId() : data.getId());
        jcStepItemMapper.delete(jcStepItem);

        //获取功能选项列表
        List<JcStepItem> jcStepItemList = data.getJcStepItemList();

        //修改功能选项信息
        if (!CollectionUtils.isEmpty(jcStepItemList)) {
            //添加功能选项
            jcStepItemList.stream().forEach(item -> jcStepItemMapper.insert(item.setStepId(StringUtils.isNotBlank(data.getStepId()) ?
                    data.getStepId() : data.getId()).setItemId(IdUtil.getId()).setCardId(data.getCardId())
                    /*.setContent(item.getItemType() == 4 ? item.getItemTitleCh() : item.getContent())
                    .setItemTitleCh(item.getItemType() == 4 ? "" : item.getItemTitleCh())*/));
        }

        //删除之前步骤关联附件
        JcStepAttachment stepAttachment = JcStepAttachment.build().setStepId(data.getStepId());
        jcStepAttachmentMapper.delete(stepAttachment);
        //添加新附件
        List<JcStepAttachment> attList = data.getAttList();
        if (!CollectionUtils.isEmpty(attList)) {
            attList.stream().forEach(att -> jcStepAttachmentMapper.insert(att.setStepId(StringUtils.isNotBlank(data.getStepId()) ? data.getStepId() : data.getId()).setCardId(data.getCardId())));
        }

        JcProceduralStep proceduralStep = JcProceduralStep.build();
        BeanUtils.copyProperties(data, proceduralStep);
        int ret = jcProceduralStepMapper.updateById(proceduralStep);
        if (ret == 1) {
            //更新版本号
            jcCardBiz.updateVersionByCardId(Integer.valueOf(requestDTO.getData().getCardId()));
            return 1;
        }
        return 0;
    }


    /**
     * 查询步骤列表
     * @param cardId  工卡id
     * @return
     */
    public List<JcStepInfoDTO> getStepNewListByCardId(String cardId,Integer type) {

        //查询步骤信息
        List<JcStepInfoDTO> list = jcProceduralStepMapper.selectProceduralStepByCardId(cardId);

        //排序
        Collections.sort(list, Comparator.comparing(JcStepInfoDTO::getStepSort));

        //查询附件信息
        List<JcStepAttachment> jcStepAttachmentList = jcStepAttachmentMapper.selectAll();

        //查询功能选项信息
        List<JcStepItem> jcStepItemList = jcStepItemMapper.selectAll();

        //通过jc_procedural_step表中的fid递归查询数据
        final List<JcStepInfoDTO> result = getNewStepTree(list, "0",jcStepAttachmentList,jcStepItemList,type);

        return result;
    }


    /**
     * 递归步骤列表
     * @param stepList
     * @param parentId
     * @return
     */
    private List<JcStepInfoDTO> getNewStepTree(List<JcStepInfoDTO> stepList, String parentId,
                                               List<JcStepAttachment> jcStepAttachmentList,List<JcStepItem> jcStepItemList,Integer type) {
        return stepList.stream().filter(step -> step.getFid().equals(parentId)).map(step ->
        {
            JcStepInfoDTO jcStepInfoDTO = BeanConvertUtils.copyProperties(step, JcStepInfoDTO.class);

            List<JcStepItem> itemList = jcStepItemList.stream().filter(toast -> toast.getStepId().equals(step.getStepId())).collect(Collectors.toList());
            List<JcStepItem> stepItemList = new ArrayList<JcStepItem>();
            List<JcStepItem> stepItemSecondList = new ArrayList<JcStepItem>();

            //app端特殊处理   所有的都存取ch
            if(type == C.N_2 ){
                itemList.stream().forEach( item ->
                        item.setContent(item.getItemType() == 4 ? item.getItemTitleCh() : item.getContent()));
            }

            //查询功能项信息
            if(CollectionUtils.isEmpty(itemList)){
                jcStepInfoDTO.setJcStepItemList(new ArrayList<JcStepItem>());
            }else{
                //警示信息提到第一位
                for(JcStepItem stepItem : itemList){
                    if(stepItem.getItemType() == 5){
                        stepItemList.add(stepItem);
                    }else{
                        stepItemSecondList.add(stepItem);
                    }
                }
                stepItemList.addAll(stepItemSecondList);
                jcStepInfoDTO.setJcStepItemList(stepItemList);
            }

            //步骤附件处理
            if(!CollectionUtils.isEmpty(jcStepAttachmentList)){
                //通过步骤id关联附件
                List<JcStepAttachment> collect = jcStepAttachmentList.stream().filter(att -> att.getStepId().equals(step.getStepId())).collect(Collectors.toList());
                jcStepInfoDTO.setAttList(collect);
            }

            List<JcStepInfoDTO> childList = getNewStepTree(stepList, jcStepInfoDTO.getStepId(), jcStepAttachmentList, jcStepItemList,type);
            jcStepInfoDTO.setChildren(childList);

            return jcStepInfoDTO;
        }).collect(Collectors.toList());
    }


    /**
     * 删除步骤
     * @param stepId  步骤id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int deleteStepById(String stepId){
        int proceduralRet = 0;
        proceduralRet = jcProceduralStepMapper.updateStepById(stepId);

        //删除步骤功能项信息
        jcStepItemMapper.deleteByStepId(stepId);

        if (proceduralRet == 1) {
            //更新版本号
            JcProceduralStep jcProceduralStep = jcProceduralStepMapper.selectOne(JcProceduralStep.build().setStepId(stepId));
            jcCardBiz.updateVersionByCardId(Integer.valueOf(jcProceduralStep.getCardId()));

            return 1;
        }
        return 0;
    }

    /**
     * 获取特殊步骤项
     * @return
     */
    public List<JcProceduralStep> getStepList() {
        List<JcProceduralStep> stepList = jcProceduralStepMapper.getStepList();
        return stepList;
    }


    /**
     * 大章节修改
     * @param requestDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer updateLargeSection(RequestDTO<JcStepInfoDTO> requestDTO) {
        JcStepInfoDTO data = requestDTO.getData();
        JcProceduralStep jcProceduralStep = JcProceduralStep.build().setStepId(data.getStepId()).setDelFlag(C.N_0);
        JcProceduralStep result = jcProceduralStepMapper.selectOne(jcProceduralStep);

        if (result != null) {
            JcProceduralStep proceduralStep = JcProceduralStep.build();
            proceduralStep.setStepId(result.getStepId());
            proceduralStep.setTitleCh(data.getTitleCh());
            int ret = jcProceduralStepMapper.updateById(proceduralStep);
            if (ret == 1) {
                //更新版本号
                jcCardBiz.updateVersionByCardId(Integer.valueOf(requestDTO.getData().getCardId()));
                return  1;
            }
        }
        return 0;
    }

    /**
     * 解析步骤json数据
     * @param requestDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer parseJsonData(RequestDTO<JcStepListDTO> requestDTO) {

        List<JcStepInfoDTO> steplist = new ArrayList<>();

        final JcStepListDTO data = requestDTO.getData();

        //工卡id
        String cardId = data.getStepList().get(0).getCardId();

        //一级数据
        final List<JcStepInfoDTO> stepList = data.getStepList();
        stepList.stream().forEach(item -> item.setFid("0"));

       //处理一级排序问题
        Integer number = 1;
        for(JcStepInfoDTO jcStepInfoDTO : stepList){
            jcStepInfoDTO.setStepSort(number);
            number++;
        }

        //封装第一级数据
        steplist.addAll(stepList);

        //递归查询封装数据
        List<JcStepInfoDTO> list = getStepData(steplist, "0");

        //组装数据
        steplist.addAll(list);

        //清空工卡相关数据
        removeData(cardId);

        //入库操作
        insertBatchData(steplist,"0");

        //更新版本号
        jcCardBiz.updateVersionByCardId(Integer.valueOf(cardId));

        return 0;
    }

    /**
     * 清空数据
     * @param cardId  工卡id
     */
    @Transactional(rollbackFor = Exception.class)
    public void removeData(String cardId){
        //清空步骤表
        jcProceduralStepMapper.deleteByCardId(cardId);
        //清空步骤功能选项表
        jcStepItemMapper.deleteByCardId(cardId);
        //清空附件表
        jcStepAttachmentMapper.deleteByCardId(cardId);
    }

    public List<JcStepInfoDTO> getStepData(List<JcStepInfoDTO> stepList,String parentId){
        List<JcStepInfoDTO> jcStepInfoDTOList = new ArrayList<JcStepInfoDTO>();
        for (JcStepInfoDTO jcStepInfoDTO : stepList){
            Integer number = 1;
            //判断是否存在子级步骤
            List<JcStepInfoDTO> list = jcStepInfoDTO.getChildren();
            if(!CollectionUtils.isEmpty(list)) {
                for(JcStepInfoDTO jcStepInfoDTO1 : list){
                    jcStepInfoDTO1.setStepSort(number);
                    jcStepInfoDTO1.setFid(jcStepInfoDTO.getStepId());
                    number++;
                }
                jcStepInfoDTOList.addAll(list);
            }

            List<JcStepInfoDTO> steplist = getStepData(list, String.valueOf(jcStepInfoDTO.getStepId()));
            jcStepInfoDTOList.addAll(steplist);
        }
        return jcStepInfoDTOList;
    }


    /**
     * 入库步骤信息数据
     * @param stepList    步骤列表
     * @param parentId    父id
     * @return
     */
    private List<JcStepInfoDTO> insertBatchData(List<JcStepInfoDTO> stepList, String parentId) {
        return stepList.stream().filter(step -> step.getFid().equals(parentId)).map(step ->
        {
            JcStepInfoDTO jcStepInfoDTO = BeanConvertUtils.copyProperties(step, JcStepInfoDTO.class);


            /**
             * 步骤
             */
            JcProceduralStep jcProceduralStep = JcProceduralStep.build();
            BeanUtils.copyProperties(jcStepInfoDTO, jcProceduralStep);
            jcProceduralStepMapper.insertUseGeneratedKeys(jcProceduralStep);

            //获取功能选项列表
            List<JcStepItem> jcStepItemList = jcStepInfoDTO.getJcStepItemList();


            //修改功能选项信息
            if (!CollectionUtils.isEmpty(jcStepItemList)) {
                //添加功能选项
                jcStepItemList.stream().forEach(item -> jcStepItemMapper.insert(item.setStepId(String.valueOf(step.getStepId())).setCardId(step.getCardId())));
            }

            //通过步骤id关联附件
            List<JcStepAttachment> attList = jcStepInfoDTO.getAttList();
            if(!CollectionUtils.isEmpty(attList)) {
                //添加附件
                attList.stream().forEach(att -> jcStepAttachmentMapper.insert(att.setStepId(step.getStepId()).setCardId(step.getCardId())));
            }

            //递归调用
            List<JcStepInfoDTO> list = insertBatchData(stepList, jcStepInfoDTO.getStepId());
            jcStepInfoDTO.setChildren(list);
            return jcStepInfoDTO;
        }).collect(Collectors.toList());
    }


    //##############################################南航二期三阶段新接口结束##################################################

}